package com.atmilan.quartz.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.atmilan.quartz.utils.product.GbProductUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.atmilan.quartz.constant.Constants;
import com.atmilan.quartz.constant.enums.ProductTypeEnum;
import com.atmilan.quartz.constant.enums.SyncStatusEnum;
import com.atmilan.quartz.model.dto.crmeb.StoreProductCrmebRequest;
import com.atmilan.quartz.model.dto.gb.GbProductResDTO;
import com.atmilan.quartz.model.entity.crmeb.StoreProduct;
import com.atmilan.quartz.model.entity.crmeb.SystemConfig;
import com.atmilan.quartz.model.entity.gb.GbProduct;
import com.atmilan.quartz.service.IGbProductService;
import com.atmilan.quartz.service.IGbSyncService;
import com.atmilan.quartz.service.IStoreProductService;
import com.atmilan.quartz.service.ISystemConfigService;
import com.atmilan.quartz.utils.source.SourceGbProductUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class GbSyncServiceImpl implements IGbSyncService {

    @Autowired
    ISystemConfigService systemConfigService;
    @Autowired
    IGbProductService gbProductService;
    @Autowired
    IStoreProductService storeProductService;
    @Autowired
    SourceGbProductUtil sourceGbProductUtil;
    @Autowired
    GbProductUtil gbProductUtil;

    @Override
    public Boolean syncGbProduct() {
        //数据清空
        gbProductService.deleteAll();
        long millis = System.currentTimeMillis();
        final ExecutorService exec = Executors.newFixedThreadPool(1);
        Callable<Map<String, GbProductResDTO>> call = () -> gbProductUtil.getGbProducts();
        try {
            Future<Map<String, GbProductResDTO>> future = exec.submit(call);
            //任务处理超时时间设为 1 小时
            Map<String, GbProductResDTO> list = future.get(1000 * 60 * 60, TimeUnit.MILLISECONDS);
            if(CollectionUtils.isEmpty(list)){
                log.info("--------------- gb获取商品接口请求失败 ---------------");
                return true;
            }
            log.info("--------------- gb远程抓取数据, 总共: {} 条, 总耗时: {} 分  ---------------", list.size(), (int) ((System.currentTimeMillis() - millis) / 1000 / 60));
            saveGoods(list);
        } catch (TimeoutException ex) {
            log.error("--------gb获取商品接口请求超时----------");
        }catch (Exception e){
            log.error("--------gb获取商品接口请求失败:{}----------",e.getMessage());
        }finally {
            exec.shutdown();
        }
        pushGbProduct();
        return true;
    }

    /**
     * 商品源数据保存
     *
     * @param
     */
    private void saveGoods(Map<String,GbProductResDTO> map) {
        List<GbProduct> collect = map.values().stream().map(e -> {
            GbProduct gbProduct = new GbProduct();
            BeanUtils.copyProperties(e, gbProduct);
            return gbProduct;
        }).collect(Collectors.toList());
        gbProductService.saveBatch(collect);
    }

    @Override
    public Boolean pushGbProduct() {
        try {
            //当次更新少于1千条, 则不更新, 并且重新拉取
            int count = gbProductService.distinctCount();
            if(100 > count){
                systemConfigService.update(Wrappers.<SystemConfig>lambdaUpdate()
                        .eq(SystemConfig :: getName, Constants.GB_SYNC_STATUS)
                        .set(SystemConfig :: getFormId, SyncStatusEnum.PUSH)
                        .set(SystemConfig :: getUpdateTime, new Date())
                );
                log.info("--------------- GB商品源数据, 少于规定条数, 不进行下发, 总条数为: {} ---------------", count);
                return false;
            }
            //将所有GB商品更新状态置为未更新
            storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                    .eq(StoreProduct :: getIsEurope, ProductTypeEnum.GB.getCode())
                    .set(StoreProduct :: getUpdateFlag, false)
            );
            //商品更新操作
            int pageNo = 1;
            int pageSize = 100;
            int maxPage = (count + pageSize - 1) / pageSize;
            log.info("--------------- 开始分页查询GB商品源数据, 本次更新总条数为: {} ---------------", count);

            long millis = System.currentTimeMillis();
            while (pageNo <= maxPage) {
                try {
                    PageHelper.startPage(pageNo, pageSize);
                    List<GbProduct> gbProducts= gbProductService.list(Wrappers.<GbProduct>lambdaQuery().groupBy(GbProduct::getIdArticolo));
                    PageInfo<GbProduct> pageInfo = PageInfo.of(gbProducts);
                    List<GbProduct> products = pageInfo.getList();
                    buildProduct(products);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                log.info("--------------- GB下发商品到数据库, 当前页数: {}, 总页数: {}, 耗时: {} 分 ---------------", pageNo, maxPage, (int) ((System.currentTimeMillis() - millis) / 1000 / 60));
                pageNo++;
            }
            // 图搜删除
            storeProductService.delSeachImage(ProductTypeEnum.GB);
            // 下架所有未更新数据
            storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                    .eq(StoreProduct::getIsEurope, ProductTypeEnum.GB.getCode())
                    .eq(StoreProduct::getUpdateFlag, false)
                    .eq(StoreProduct :: getIsShow, true)
                    .eq(StoreProduct :: getIsDel, false)
                    .set(StoreProduct::getIsShow, false)
                    .set(StoreProduct::getStock, 0)
                    .set(StoreProduct::getLastPushTime, new Date())
                    .set(StoreProduct::getIsTusou, false)
                    );
            // 下架所有sku库存
            storeProductService.downloadSku(ProductTypeEnum.GB.getCode());
            
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 商品构建处理
     * @param products
     */
    private void buildProduct(List<GbProduct> products) {
        try {
            for (GbProduct product : products) {
                //商品没有图片，跳过
                List<String> picList = Stream.of(product.getUrlImg1(), product.getUrlImg2(), product.getUrlImg3(), product.getUrlImg4(), product.getUrlImg5()).collect(Collectors.toList());
                picList.removeIf(StringUtils::isBlank);
                if(CollectionUtils.isEmpty(picList)){
                    log.info("--------------- 该商品: {} 没有图片, 不进行下放 ---------------",product.getIdArticolo());
                    continue;
                }
                List<GbProduct> skus = gbProductService.list(Wrappers.<GbProduct>lambdaQuery().eq(GbProduct::getIdArticolo, product.getIdArticolo())
                        .isNotNull(GbProduct::getTaglia).gt(GbProduct::getDisponibilita, 0));
                List<GbProduct> exceptionList = new ArrayList<>();
                for (GbProduct gbProduct : skus) {
                    if(StringUtils.isBlank(gbProduct.getPrezzoImponibileNetto()) || new BigDecimal(gbProduct.getPrezzoImponibileNetto()).compareTo(BigDecimal.ZERO) < 1){
                        log.info("--------------- 该商品sku: {} 售价异常, 不进行下放 ---------------",gbProduct.getCodArticolo());
                        exceptionList.add(gbProduct);
                    }
                }
                skus.removeAll(exceptionList);
                if (CollectionUtils.isEmpty(skus)) {
                    continue;
                }
                // 库存计算
                int stock = 0;
                for (GbProduct sku : skus) {
                    stock += Integer.parseInt(sku.getDisponibilita());
                }
                // 构建实体
                StoreProductCrmebRequest storeProductCrmebRequest = sourceGbProductUtil.buildGBProduct(product, skus);
                // 数据保存
                StoreProduct storeProduct = storeProductService.getByBarCode(storeProductCrmebRequest.getBarCode(), storeProductCrmebRequest.getSuppliersId(), storeProductCrmebRequest.getKeyword());
                boolean crmebUpdate = true;
                if (null != storeProduct && null != storeProduct.getLastPushTime()) {
                    long txyye = (System.currentTimeMillis() - storeProduct.getLastPushTime().getTime()) / 1000 / 60;
                    if (60 > txyye) {
                        log.info("--------------- 该商品: {} 上次GB更新时间: {} 小于一小时, 不进行更新 ---------------", storeProductCrmebRequest.getBarCode(), storeProduct.getLastPushTime());
                        crmebUpdate = false;
                        storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                                .eq(StoreProduct::getId, storeProduct.getId())
                                .set(StoreProduct::getUpdateFlag, true)
                        );
                    }
                }
                if (crmebUpdate) {
                    storeProductService.saveOtProduct(storeProductCrmebRequest, storeProduct, stock);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}
